The Atari XL Parallel
Bus Interface - Part 3
By Roland Scholz
The last two articles
have shown which signals have to be used
to form a PBI device that conforms to the
Atari specification. This device is noticed
and embedded into the during the power up
procedure. As mentioned before, the math-pack-disable
(MPD\) signal plays an important role, since
it is responsible for switching off the
internal Math-ROM and turning on the device's
ROM if it is activated using the address
NEWPORT ($D1FF).
Now we are going
to consider the data structure that has
to be programmed into the ROM, to enable
the OS to recognize the device:

Figure 1: ROM vector table
($D800- $D81C), fields marked with * do
not have to be filled in.
The first three fields
can hold information about the checksum
and version of firmware contained in the
ROM. This information as well as the device
name and type is not checked by the OS and
can be left out. All other fields have to
be filled correctly, otherwise the computer
will probably hang.
After pressing the
reset key the OS turns off any active PBI
device. After this, each bit of NEWPORT
is serially set to 1. Then locations $D808
and $D80B are checked for the values $80
and $91 respectively. If both are true (the
Math-ROM contains other values, of course),
the OS performs a subroutine jump to $D819.
A PBI ROM usually contains a JMP ($4C) statement
followed by an address to the initialization
routine in the device's ROM. This routine
can be used to initialize registers and
insert the device into the operation systemÆs
device table (HATABS).
The following figure
shows an example of a possible data structure
and init-routine.
DUMMY
ORG $D800
PBITAB
DFB $CA,$FE,0
Checksum and ROM version
(values
donÆt care)
DFB $80
ID-Number 1
DFB 0
Device-Type
JMP SIOVEC
SIO I/O-Vector
JMP IRQVEC
IRQ IRQ-Vector
DFB $91
ID-Number 2
DEVNAME
DFB 'Z
Handler-Name
DFW OPEN-1
HATABS-entries
DFW CLOSE-1
DFW GET-1
DFW PUT-1
DFW CLOSE-1
DFW SPECIAL-1
JMP INIT
DFB 0 |
Figure 2: PBI data-structure.
NEWDEV
EQU $E486
GENDEV
EQU $E48F
DEVMASK
EQU $247
PBI-device already
known to
the
OS
NDEVREQ
EQU $248
Activated PBI-devive
HATABS
EQU $31A
*
ORG $somewhere
*
SIOVEC
CLC
All SIO calls try to
use the
PBI-device.
We do not
want to
implement
a SIO driver, so CLC
and
RTS tell SIO we do not handle
its
requests.
IRQVEC
RTS
Our implementation
does not use
interrupts.
*
*
The device is registered
to the OS by setting
*
the appropriate bit in the DEVMASK
register
*
and the CIO handler is registered
in the HATABS
*
table by calling the NEWDEV
routine
*
INIT
LDA DEVMASK
ORA NDEVREQ
STA DEVMASK
LDX DEVNAME
LDA #GENDEV:H
LDY #GENDEV:L
JSR NEWDEV
STA HATABS+1,x
TYA
STA HATABS,x
...
... Code device-specific
initializations here
...
...
RTS
OPEN
...
...
CLOSE
LDY #1
SEC
RTS
GET
...
...
PUT
...
...
SPECIAL
...
... |
Figure 3: Code example
for initialization of PBI-devices.
Since the OS finds
the corresponding ID values $80 and $91
at the given addresses, it performs a subroutine
jump to $D819. Through the JMP statement
execution continues at the routine INIT.
There the register DEVMASK containing all
PBI-devices that have been found so far
is read. To this value the bit of the actual
activated device (stored in NDEVREQ) is
OR-ed and the result is saved back to DEVMASK.
This ensures the OS always knows about out
device. The next task is to read the device
character under which the device is known
to the CIO. This can be any character, however
we should be careful and not override such
devices as D: or E: without knowing exactly
what we are doing. In the example the driver
would be registered under the name Z: which
is done using the routine NEWDEV.
The routine takes
the name of the device in register X and
the address of the CIO handler table in
the accumulator and Y-register. We are going
to register the generic handler GENDEV which
is a part of the OS specially written to
easily support PBI devices. The routine
NEWDEV will end up with following return-codes:
Negative bit set: HATABS is
full, the entry could not be written.
Carry bit clear: The entry
has been successfully written to the
table.
Carry bit set: The table already
contains the requested entry, the X
register holds the index to the
entry found.
For this example
we do not care about the return codes, instead
we just write our handler address into the
table. After this the hardware registers
of the device can be initialized and using
RTS we jump back to the calling OS power-up
routine.
So far we have registered
a certain character as a handler name and
we have told the OS there is a PBI device
that can be activated using a certain bit
in NEWPORT. The last thing to describe is
the procedure the GENDEV generic handler
undergoes if we try to communicate with
the registered Z: handler. We assume a BASIC
program would perform an OPEN #2,4,0,ôZ:ô
statement, in other words channel #2 is
to be opened for reading using the handler
Z:
Utilizing the CIO
handler table HATABS the OS figures out
the generic PBI-device driver is to be used
to perform that action. GENDEV then activates
all registered PBI devices one by one and
jumps to the open routine through the open
vector contained in the data structure.
The open routine should then check if it
supports the given handler name (Z:) by
checking the content of address IOCBCHIDZ
($20). If it does not, it has to clear the
carry flag and to jump back via RTS, so
the generic handler can try the next device.
If the open routine finds it is the ôrightô
routine, all actions to open the channel
should be done here and a RTS has to be
performed with carry bit set, so the generic
habdler knows the open action has been performed
correctly.
The CIO return-code
has to be put back in the Y register and
should be 1 if the action was performed
correctly. All other functions usually implemented
by a device handler (open, close, get, put,
status, special) work in the same way; if
the function is performed correctly, the
carry bit has to be set and the CIO return
code is contained in register Y.
Several PBI devices
can share the GENDEV driver as long as each
firmware checks whether it is the one the
OS wants to call.
The next article
will show a full-function implementation
of a PBI device.The device acts as an interface
to PC-cards like multi-I/O (RS232, Centronics)
or Hercules graphics cards. The interface
consists of both hardware and software (firmware)
of which some details will be considered.
roland_scholz@web.de |